package org.wevil.util;

import net.sourceforge.pinyin4j.PinyinHelper;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串操作工具类
 *
 * @author wanglei
 * @since 2019/5/21
 */
public class StringUtil {

    // ============================ 常量 =======================================================//

    /** space 空格 */
    public static final String SPACE = " ";
    /** empty 空字符串 */
    public static final String EMPTY = "";
    /** return 回车，使光标回到行首 */
    public static final String CR = "\r";
    /** newline 换行，使光标下移一格 */
    public static final String LF = "\n";
    /** tab 制表符 */
    public static final String TAB = "\t";

    /** newline windows */
    public static final String NEWLINE_WIN = "\r\n";
    /** newline linux or unix */
    public static final String NEWLINE_LINUX_UNIX = "\n";
    /** newline mac os */
    public static final String NEWLINE_MAC = "\r";


    // ============================ 变量 =======================================================//

    private static String str;

    public static String getStr() {
        return str;
    }

    public static void setStr(String str) {
        StringUtil.str = str;
    }

    // ============================ 公共类 =======================================================//

    // ============================ 截取  =======================================================//

    /**
     * 截取字符串最后几位，长度不够则直接返回
     *
     * @author wevil
     * @since 2023/10/17
     * */
    public static String subLast(String str, int lastNum){
        if(str.length()<=lastNum){
            return str;
        }
        return str.substring(str.length()-lastNum);
    }

    /**
     * 截取字符串指定长度，多的部分用指定字符串代替。不足的显示原有长度
     *
     * @param str 要截取的字符串
     * @param begin 截取起始下标
     * @param end 截取结束下标
     * @param endStr 结尾代替字符串
     * @since 2022/2/28
     * */
    public static String substring(String str, int begin, int end, String endStr){
        // 定义截取后的字符串
        String subStr = str;
        // 获取原有长度
        int length = str.length();
        // 获取截取长度
        int subLength = end - begin;
        if(length > subLength){ // 如果截取长度足够
            subStr = str.substring(begin, end) + endStr;
        }
        return subStr;
    }

    // ============================ 判断 =======================================================//

    /**
     * 判断字符串是为为空。null, "", " "都会判定为空。
     *
     * @author wanglei
     * @since 2021/6/25
     * */
    public static boolean isBlank(String str){
        return StringUtils.isBlank(str);
    }

    /**
     * 判断字符串不为空。空格也算为空
     *
     * @since 2022/4/13
     * */
    public static boolean isNotBlank(String str){
        return str != null && !str.trim().equals("");
    }

    /**
     * 判断带逗号分隔的数组字符串是否相同，忽略顺序 例如： "1,2,3" 和 "2,1,3"相同
     * */
    public static boolean areIdsEqual(String ids1, String ids2){
        // 处理空字符串或全空格的情况（根据实际需求调整）
        if (ids1 == null && ids2 == null) {
            return true;
        }
        if (ids1 == null || ids2 == null) {
            return false;
        }
        ids1 = ids1.trim();
        ids2 = ids2.trim();
        if (ids1.isEmpty() && ids2.isEmpty()) {
            return true;
        }
        // 按逗号分割成数组，再转换为 Set
        Set<String> set1 = new HashSet<>(Arrays.asList(ids1.split(",")));
        Set<String> set2 = new HashSet<>(Arrays.asList(ids2.split(",")));
        // 比较两个 Set 是否相等（元素完全相同）
        return set1.equals(set2);
    }

    // ============================ 截取  =======================================================//

    /**
     * 反转字符串
     *
     * @author wevil
     * @since 2023/9/25
     * */
    public static String reverse(String str){
        return new StringBuilder(str).reverse().toString();
    }



    /**
     * 去除字符串尾部的空格与换行符 \r\n
     *
     * @author wanglei
     * @since 2020/11/11
     */
    public static String trimSuffix(String str, String... symbols) {
        setStr(str);
        trimSuffixUtil(symbols);
        return getStr();
    }

    /**
     * 字符串格式化为指定长度，没有的部分空格补齐
     */
    public static String formatStr(String str, int length) {
        if (str == null) {
            str = "";
        }
        int strLen = getStrLength(str);
        // 如果字符串长度等于定义的长度，直接返回
        if (strLen == length) {
            return str;
        }
        // 如果小于
        else if (strLen < length) {
            int temp = length - strLen;
            StringBuilder tem = new StringBuilder();
            for (int i = 0; i < temp; i++) {
                tem.append(" ");
            }
            return str + tem;
        } else {
            return str.substring(0, length);
        }

    }

    /**
     * 获取两个字符串相同的字符
     */
    public static Collection<String> get2StringSameChar(String str1, String str2) {
        Set<String> set1 = new HashSet<>();
        Set<String> set2 = new HashSet<>();
        for (int i = 0; i < str1.length(); i++) {
            set1.add(str1.substring(i, i + 1));
        }
        for (int i = 0; i < str2.length(); i++) {
            set2.add(str2.substring(i, i + 1));
        }
        // 找出两个元素的交集
        set1.retainAll(set2);
        return set1;
    }

    /**
     * 获取路径里的文件名
     */
    public static String getFileNameByPath(String path) {
        int index = path.lastIndexOf("\\");
        return path.substring(index + 1);
    }

    /**
     * 获取路径里路径部分
     */
    public static String getPathByPath(String path) {
        int index = path.lastIndexOf("\\");
        return path.substring(0, index + 1);
    }

    /**
     * 获取文件名的扩展名
     */
    public static String getFileExtension(String fileName) {
        fileName = fileName.substring(fileName.lastIndexOf(".") + 1);
        return fileName;
    }

    /**
     * 读取字符串中某个字符串出现的字数
     */
    public static int countStr(String string, String str) {
        int fromIndex = 0;
        int count = 0;
        while (true) {
            int index = string.indexOf(str, fromIndex);
            if (-1 != index) {
                fromIndex = index + 1;
                count++;
            } else {
                break;
            }
        }
        return count;
    }

    /**
     * 通过正则表达式匹配字符串里的内容，然后将匹配到的替换为（指定内容+原有匹配内容）
     *
     * @param str       字符串
     * @param regex     正则表达式
     * @param appendStr 要追加的内容
     */
    public static String matchReplaceAppend(String str, String regex, String appendStr) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String group = matcher.group();
            matcher.appendReplacement(sb, appendStr + group);
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 仅限 格式化主要职能使用
     * 格式化填写的数据对  数字 + 、进行分段处理
     *
     * @param text 需要处理的字符串
     * @return
     */
    public static String formatString(String text) {
        text = text.replace(" ", "");
        text = text.replace("\r\n", "");
        text = text.replace("\n", "");
        text = StringUtil.matchReplaceAppend(text, "(\\d+、)", "\r\n    ").trim();
        if (!Pattern.matches("^1、.*", text) || !Pattern.matches("^一、.*", text)
                || !Pattern.matches("^(1).*", text)) {
            String[] strings = text.split("\r\n");
            text = "    ";
            for (int i = 0; i < strings.length - 1; i++) {
                text += NumberUtil.trimRightSymbol(strings[i]) + "。\r\n";
            }
            text += NumberUtil.trimRightSymbol(strings[strings.length - 1]) + "。";
        } else {
            text = text.substring(2);
        }
        return text;
    }

    /**
     * 删除字符串所有空格含中文
     *
     * @param string
     * @return
     */
    public static String deleteSpace(String string) {
        if (string == null) {
            return "";
        }
        String cellVal = string.replaceAll("\\s*", "");
        cellVal = cellVal.replaceAll("[\\s\\p{Zs}]+", "");
        return cellVal;
    }


    // ============================ 转换 =======================================================//

    /**
     * 下划线转驼峰
     * */
    public static String under2Camel(String underStr){
        // 先将下划线转换为大写的字符，然后用空格分隔
        String[] parts = underStr.toLowerCase().split("_");
        StringBuilder camelCaseString = new StringBuilder();
        for (int i = 0; i < parts.length; i++) {
            // 第一个单词保持原样，其余单词首字母大写
            if (i > 0) {
                camelCaseString.append(parts[i].substring(0, 1).toUpperCase());
                camelCaseString.append(parts[i].substring(1).toLowerCase());
            } else {
                camelCaseString.append(parts[i]);
            }
        }
        return camelCaseString.toString();
    }

    /**
     * 将给定的汉字字符串转换为拼音首字母字符串。
     *
     * @param chineseText 汉字字符串
     * @return 拼音首字母字符串
     */
    public static String convertPinYinFirst(String chineseText) {
        StringBuilder initialsBuilder = new StringBuilder();
        for (char c : chineseText.toCharArray()) {
            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c);
            if (pinyinArray != null && pinyinArray.length > 0) {
                // 取第一个拼音作为首字母
                initialsBuilder.append(pinyinArray[0].charAt(0));
            } else {
                // 非汉字字符原样保留
                initialsBuilder.append(c);
            }
        }
        return initialsBuilder.toString();
    }


    // ============================ 私有类 =======================================================//

    /**
     * 获取字符串的长度， 中文按2个空格处理，其他按照一个空格处理
     */
    private static int getStrLength(String str) {
        char[] strArray = str.toCharArray();
        int strLength = 0;
        for (char c : strArray) {
            if (isChinese(c)) {
                strLength += 2;
            } else {
                strLength += 1;
            }
        }
        return strLength;
    }

    /**
     * 字符是否中文
     */
    private static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
    }

    /**
     * 去除字符串尾部的空格与换行符 \r\n
     *
     * @author wanglei
     * @since 2020/11/11
     */
    private static void trimSuffixUtil(String... symbols) {
        if (symbols != null && symbols.length > 0) {
            for(String symbol : symbols){
                if(str.endsWith(symbol)){
                    str = str.substring(0, str.length()-symbol.length());
                    trimSuffixUtil(symbols);
                }
            }
        }
    }
}